#ifndef DEFAULT_H_
#define DEFAULT_H_

/* "Booleans para convergência dos métodos */
#define B_FALSE   0
#define B_TRUE    1

/* Precisão em dígitos */
#define NDIGITS 10000001

/* Precisão em bits = ceil( NDIGITS * log2(10) ) */
#define PREC    33219281

/* Define a forma de calcular Pi */
#define SEQUENTIALLY 1
#define CONCURRENTLY 2

/* Define os métodos utilizados para calcular Pi */
#define GAUSS_LEGENDRE 1
#define BORWEIN        2
#define MONTE_CARLO    3

/* Define os arquivos aonde será salvo o valor de Pi */
#define GAUSS_LEGENDRE_FILE      "pi/gauss-legendre.txt"
#define BORWEIN_FILE             "pi/borwein.txt"
#define MONTE_CARLO_FILE         "pi/monte-carlo.txt"
#define GAUSS_LEGENDRE_CONC_FILE "pi/gauss-legendre-conc.txt"
#define BORWEIN_CONC_FILE        "pi/borwein-conc.txt"
#define MONTE_CARLO_CONC_FILE    "pi/monte-carlo-conc.txt"

/* Define regras para o cálculo do índice cíclico. Por exemplo:
   Isso evita ficar atribuindo de m[1] para m[0] para deixar o valor antigo sempre em m[0] 
   m[0] será o valor antigo quando i for par e, quando ímpar, m[1] será o valor antigo */
#define INDEX(i,j,k) (i+j)%k
#define INDEX2(i,j) INDEX(i,j,2)
#define INDEX3(i,j) INDEX(i,j,3)

#include <stdio.h>
#include <gmp.h>
#include <string.h>
#include <sys/time.h>
#include <unistd.h>
#include <pthread.h>

#include "borwein.h"
#include "gauss-legendre.h"
#include "monte-carlo.h"

/* Precisão cujo valor é 0,000000000000000..........1 */
/* É global para evitar recálculo */
mpf_t prec;

/* Inicia a precisão */
void init_prec();

/* Limpa a precisão */
void clear_prec();

/* Executa um método para calcular Pi */
/* Saídas: it - iterações; time - tempo em segundos; file - arquivo aonde foi salvo o Pi */
void execute_method(int how, int method, mpf_t pi, long *it, int *time, char *file);

/* Verifica a convergência de dois valores utilizando a variável prec */
int has_converged(mpf_t a0, mpf_t a1);

/* Verifica a convergência de dois valores utilizando precisão de 5 casas decimais */
int has_kind_of_converged(mpf_t a0, mpf_t a1);

/* Salva o valor de Pi em um arquivo */
void save_pi(mpf_t pi, char *file);

#endif /* DEFAULT_H_ */
